package com.hhsjtest.composiable.scroll;

import static com.hhsjtest.composiable.scroll.ScrollStateUtil.SCROLL_DOWN;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.SCROLL_UP;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.TOP;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.TOP_BELOW;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.listViewPosition;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.scrollMode;
import static com.hhsjtest.composiable.scroll.ScrollStateUtil.scrollModeName;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class InnerListView extends ListView {


    private RootScrollView parentScrollView;
    float lastY = 0;
    boolean interceptState = false;
    //0,-1,1
    int parentState = 0;

    public InnerListView(Context context) {
        super(context);
        init();
    }

    public InnerListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public InnerListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    void init() {
        //ListView可以设置阻尼，值越大，阻力越大
        setFriction(ViewConfiguration.getScrollFriction());
        setBackgroundColor(Color.BLUE);
    }

    int[] listItemHeight = new int[0];

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(new MAdapter(adapter));
        int count = adapter.getCount();
        listItemHeight = new int[count];
    }

    public int getHideY() {
        if (getChildCount() == 0) {
            return 0;
        }

        int height = 0;
        int firstVisiblePosition = getFirstVisiblePosition();
        View childO = getChildAt(0);
        height = (int) Math.abs(childO.getY());
        for (int i = 0; i < firstVisiblePosition; i++) {
            height += listItemHeight[i];
        }
        return height;
    }

    boolean moveHandled = false;

    public boolean handleMove() {
        return moveHandled;
    }

    private class MAdapter extends BaseAdapter {

        ListAdapter baseAdapter;

        public MAdapter(ListAdapter baseAdapter) {
            this.baseAdapter = baseAdapter;
        }

        /**
         * How many items are in the data set represented by this Adapter.
         *
         * @return Count of items.
         */
        @Override
        public int getCount() {
            return baseAdapter.getCount();
        }

        @Override
        public Object getItem(int position) {
            return baseAdapter.getItem(position);
        }

        @Override
        public long getItemId(int position) {
            return baseAdapter.getItemId(position);
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = baseAdapter.getView(position, convertView, parent);
            view.post(new Runnable() {
                @Override
                public void run() {
                    listItemHeight[position] = view.getMeasuredHeight();
                }
            });
            return view;
        }
    }

    public void setParentScrollView(RootScrollView rootScrollView) {
        this.parentScrollView = rootScrollView;
    }

    @Override
    protected void detachViewFromParent(int index) {
        super.detachViewFromParent(index);
        parentScrollView = null;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (parentScrollView == null) return super.dispatchTouchEvent(ev);

        final int action = ev.getActionMasked();
        final float currentY = ev.getY();

        if (action == MotionEvent.ACTION_DOWN) {
            super.dispatchTouchEvent(ev);
            lastY = currentY;
            return true;
        }
        if (action == MotionEvent.ACTION_MOVE) {
            final int scrollMode = scrollMode((int) currentY, (int) lastY);
            Log.e("HHSJ", "=====List dispatch move");
            boolean dispatch = super.dispatchTouchEvent(ev);
            Log.e("HHSJ", "=====List dispatch move : " + dispatch);
            return dispatch;
        }

        if (action == MotionEvent.ACTION_UP) {
            Log.e("HHSJ", "=====List dispatch UP");
        }

        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (parentScrollView == null) return super.onTouchEvent(ev);
        final int action = ev.getActionMasked();
        if (action == MotionEvent.ACTION_DOWN) {
            lastY = ev.getY();
            return super.onTouchEvent(ev);
        }
        if (action == MotionEvent.ACTION_MOVE) {
            Log.e("HHSJ", "=====List touch move");
            final float currentY = ev.getY();
            final int scrollMode = scrollMode((int) currentY, (int) lastY);
            Log.e("HHSJ", "=====List dispatch move " + scrollModeName(scrollMode));
            final int listViewPosition = listViewPosition(parentScrollView.getScrollY(), (int) getY());
            switch (listViewPosition) {
                case TOP://ListView 在ScrollView顶部
                    lastY = currentY;
                    if (scrollMode == SCROLL_DOWN) {//下拉
                        if (canScrollVertically(-1)) {//可以下拉
                            moveHandled = true;
                            boolean touch = super.onTouchEvent(ev);
                            Log.e("HHSJ", "在顶部，下拉，可以下滚，  ListView 自己处理 已经走super.onTouch;");
                            return touch;
                        } else {
                            Log.e("HHSJ", "在顶部，下拉，不能下滚， ListView 不处理;");
                        }
                    }

                    if (scrollMode == SCROLL_UP) {
                        moveHandled = true;
                        boolean touch = super.onTouchEvent(ev);
                        Log.e("HHSJ", "在顶部，上拉，不关心可不可以滚动，  ListView 都自己处理 已经走super.onTouch;");
                        return touch;
                    }
                    break;
                case TOP_BELOW://ListView还未到达ScrollView顶部
                    //ListView 不在ScrollView顶部，如果ScrollView分发了下滑，
                    if (scrollMode == SCROLL_DOWN) {
                        /**
                         * ListView没有到达顶部，但是可以下拉，这是一个异常情况，需要处理以下，让ListView先滚下啦
                         */
                        if (canScrollVertically(-1)) {
                            moveHandled = true;
                            boolean touch = super.onTouchEvent(ev);
                            Log.e("HHSJ", "不在顶端，由于ListView可下滑，需要处理异常： ListView 自己处理 已经走super.onTouch;");
                            return touch;
                        }
                    }
                    /**
                     * 其他情况，ListView都不应该触发滚动，所以不能调用onTouchEvent
                     */
                    Log.e("HHSJ", "不在顶端，不管上滑，还是下滑， ListView 都不处理;");
                    break;
                default://这是一个异常情况，ListView超过了ScrollView的顶端，只能交给ScrollView的onTouch处理
                    Log.e("HHSJ", "=====List touch move " + String.format("Scroll: %d, Y: %d", parentScrollView.getScrollY(), (int) getY()));
                    break;
            }
            moveHandled = false;
            return true;
        }
        if (action == MotionEvent.ACTION_UP) {
            Log.e("HHSJ", "=====List touch UP");
            //如果ListView滚动过，就让他自己调用，如果没有，就不能调用
            final boolean isListAtTop = getY() == parentScrollView.getScrollY();
            if (!isListAtTop) {
                Log.e("HHSJ", "=====List touch UP 不在顶部，不让滚");
                //目的是让ListView产生最大的阻尼，从而限制其滚动，同时让ListView回到第0条。
                setFriction(Float.MAX_VALUE);
                setSelection(0);
            } else {
                Log.e("HHSJ", "=====List touch UP 在顶部，让滚");
                //恢复ListView的阻尼
                setFriction(ViewConfiguration.getScrollFriction());
            }
        }
        if (action == MotionEvent.ACTION_CANCEL) {
            Log.e("HHSJ", "=====List touch CANCEL");
            //如果move被cancel，需要设置到 0
            setSelection(0);
        }
        return super.onTouchEvent(ev);
    }

}
